package com.ocm.tourism.core.service;

import com.ocm.tourism.core.dao.CataloguesDao;
import com.ocm.tourism.core.dao.CulinaryCultureDao;
import com.ocm.tourism.core.dao.HotelDao;
import com.ocm.tourism.core.dao.TranslationDao;
import com.ocm.tourism.core.domain.AttractionBusiness;
import com.ocm.tourism.core.domain.AttractionCatalogue;
import com.ocm.tourism.core.domain.Catalogues;
import com.ocm.tourism.core.domain.CataloguesFileInfo;
import com.ocm.tourism.core.domain.CulinaryCulture;
import com.ocm.tourism.core.domain.Hotel;
import com.ocm.tourism.core.domain.LanguageType;
import com.ocm.tourism.core.domain.SightSeeing;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class CataloguesServiceImpl implements CataloguesService {

   @Autowired
   CataloguesDao cataloguesDao;

   @Autowired
   HotelDao hotelDao;
   
   @Autowired
   CulinaryCultureDao culinaryCultureDao;

   @Autowired
   TranslationDao translationDao;

   public long countAllCatalogueses() {
      return cataloguesDao.count();
   }

   @Transactional
   public void deleteCatalogues(Catalogues catalogues) {
      cataloguesDao.remove(catalogues.getId());
   }

   public Catalogues findCatalogues(Long id) {
      return cataloguesDao.find(id);
   }

   public List<Catalogues> findAllCatalogueses() {
      return cataloguesDao.findAll();
   }

   public List<Catalogues> findCataloguesEntries(int firstResult, int maxResults) {
      return cataloguesDao.findEntries(firstResult, maxResults);
   }

   @Transactional
   public void saveCatalogues(Catalogues catalogues) {
      if (catalogues.getId() == null || catalogues.getId() == 0){
         cataloguesDao.save(catalogues);
         if (LanguageType.isNotDefault()){
            translationDao.saveCatalogues(catalogues);
         }
      }else{
         updateCatalogues(catalogues);
      }
   }

   @Transactional
   public Catalogues updateCatalogues(Catalogues catalogues) {
      if (LanguageType.isNotDefault()){
         translationDao.saveCatalogues(catalogues);
      }else {
         catalogues = cataloguesDao.update(catalogues);
      }
      return catalogues;
   }

   @Override
   public Catalogues findCatalogues(String newType) {
      Catalogues catalogues = cataloguesDao.find(newType);
      if (catalogues != null){
         if (LanguageType.isNotDefault()){
            catalogues = this.translationDao.find(catalogues);
         }
      }
      return catalogues;
   }

   @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
   public void linkHotels(Catalogues catalogues, List<Long> hotelIds) {
      List<AttractionBusiness> attractionBusinesses = catalogues.getAttractionBusinesses();
      if (hotelIds != null && hotelIds.size() > 0){
      List<Hotel> actualHotels = this.hotelDao.findAll(hotelIds);
      for (Hotel hotel : actualHotels){
         AttractionBusiness attractionBusiness = new AttractionBusiness();
         attractionBusiness.setCatalogues(catalogues);
         attractionBusiness.setBusiness(hotel);
         if (!attractionBusinesses.contains(attractionBusiness)){
            attractionBusinesses.add(attractionBusiness);
         }
      }
      }
      if (catalogues.getId() == null || catalogues.getId() == 0)
         cataloguesDao.save(catalogues);
      else
         cataloguesDao.update(catalogues);
   }

   @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
   public void linkFoods(Catalogues catalogues, List<Long> culinaryCultureIds) {
      List<AttractionBusiness> attractionBusinesses = catalogues.getAttractionBusinesses();
      if (culinaryCultureIds != null && culinaryCultureIds.size() > 0){
      List<CulinaryCulture> actuals = this.culinaryCultureDao.findAll(culinaryCultureIds);
      for (CulinaryCulture culinaryCulture : actuals){
         AttractionBusiness attractionBusiness = new AttractionBusiness();
         attractionBusiness.setCatalogues(catalogues);
         attractionBusiness.setBusiness(culinaryCulture);
         if (!attractionBusinesses.contains(attractionBusiness)){
            attractionBusinesses.add(attractionBusiness);
         }
      }
      }
      if (catalogues.getId() == null || catalogues.getId() == 0)
         cataloguesDao.save(catalogues);
      else
         cataloguesDao.update(catalogues);
   }
   
   @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
   public void linkCatalogues(Catalogues catalogues, List<Long> catalogueIds) {
      List<AttractionCatalogue> attractionCatalogues = catalogues.getAttractionCatalogues();
      if (catalogueIds != null && catalogueIds.size() > 0){
      List<Catalogues> actualCatalogues = this.cataloguesDao.findAll(catalogueIds);
      for (Catalogues actualCatalogue : actualCatalogues){
         AttractionCatalogue attractionCatalogue = new AttractionCatalogue();
         attractionCatalogue.setCatalogues(catalogues);
         attractionCatalogue.setLinkedCatalogue(actualCatalogue);
         if (!attractionCatalogues.contains(attractionCatalogue)){
            attractionCatalogues.add(attractionCatalogue);
         }
      }
      }
      if (catalogues.getId() == null || catalogues.getId() == 0)
         cataloguesDao.save(catalogues);
      else
         cataloguesDao.update(catalogues);
   }
   
   @Override
   public List<CataloguesFileInfo> findFoodSpecials(int firstResult, int maxResults) {
      List<CataloguesFileInfo> cataloguesFileInfos = this.cataloguesDao.findCataloguesFileInfos(firstResult, maxResults, "foodspecial");
      return cataloguesFileInfos;
   }

   @Override
   public long countFoodSpecials() {
      long count = this.cataloguesDao.countCataloguesFileInfos("foodspecial");
      return count;
   }

   @Override
   public CataloguesFileInfo findCataloguesFileInfos(Long id) {
      CataloguesFileInfo cataloguesFileInfo = this.cataloguesDao.findCataloguesFileInfo(id);
      return cataloguesFileInfo;
   }

   @Override
   public SightSeeing findSightSeeing(Long sightseeingId) {
      SightSeeing sightSeeing = this.cataloguesDao.findSightSeeing(sightseeingId);
      return sightSeeing;
   }
}
